<template>
  <div class="container fade-in">
    <div class="header">
      <h2 class="section-title">用户详情</h2>
      <div class="actions">
        <button class="btn secondary" @click="goBack">
          <span class="icon">⬅️</span>
          返回
        </button>
        <button class="btn secondary" @click="refreshPage">
          <span class="icon">🔄</span>
          刷新
        </button>
      </div>
    </div>

    <!-- 基本信息 -->
    <div class="card slide-up" style="animation-delay: 0.1s">
      <h3>基本信息</h3>
      <div class="grid">
        <div class="grid-item"><label>头像</label>
          <div class="avatar-wrap">
            <img v-if="avatarUrl" :src="avatarUrl" class="avatar" alt="头像" />
            <div v-else class="avatar placeholder">👤</div>
          </div>
        </div>
        <div class="grid-item"><label>用户ID</label><div>{{ userId }}</div></div>
        <div class="grid-item"><label>用户名</label><div>{{ basic.name || '-' }}</div></div>
        <div class="grid-item"><label>手机号</label><div>{{ basic.phone || '-' }}</div></div>
        <div class="grid-item"><label>邮箱</label><div>{{ basic.email || '-' }}</div></div>
        <div class="grid-item"><label>状态</label><div><span class="badge" :class="enableBadge(basic.enableStatus)">{{ enableText(basic.enableStatus) }}</span></div></div>
        <div class="grid-item"><label>最近登录</label><div>{{ formatDate(basic.lastLoginTime) }}</div></div>
        <div class="grid-item"><label>创建时间</label><div>{{ formatDate(basic.creationTime) }}</div></div>
      </div>
    </div>

    <!-- 账户余额 -->
    <div class="card slide-up" style="animation-delay: 0.2s">
      <h3>账户余额</h3>
      <div v-if="viewingSelf">
        <div class="grid">
          <div class="grid-item"><label>未结算余额</label><div>{{ (account.unsettledBalance ?? 0).toFixed(2) }}</div></div>
          <div class="grid-item"><label>可提现余额</label><div>{{ (account.withdrawableBalance ?? 0).toFixed(2) }}</div></div>
          <div class="grid-item"><label>分账余额</label><div>{{ (account.dividedBalance ?? 0).toFixed(2) }}</div></div>
        </div>
      </div>
      <!-- 非当前用户不展示提示文案，保持页面简洁 -->
    </div>

    <!-- 关联角色列表 -->
    <div class="card slide-up" style="animation-delay: 0.3s">
      <div class="table-header"><h3>关联角色列表</h3></div>
      <div class="filters" style="margin-top:8px">
        <div class="filter-row">
          <label class="filter-label">关键字</label>
          <input v-model="roleFilters.key" class="input" placeholder="成员昵称关键词" />
          <label class="filter-label">商户ID</label>
          <input v-model="roleFilters.merchantId" class="input" placeholder="可选" style="width:180px" />
          <label class="filter-label">门店ID</label>
          <input v-model="roleFilters.storeId" class="input" placeholder="可选" style="width:180px" />
          <label class="filter-label">角色类型</label>
          <select v-model.number="roleFilters.roleType" class="input" style="width:140px">
            <option :value="-1">不限</option>
            <option :value="0">成员</option>
            <option :value="1">管理员</option>
            <option :value="2">店员</option>
          </select>
          <button class="btn secondary" @click="searchRoles">搜索</button>
          <button class="btn secondary" @click="resetRoleFilters">重置</button>
        </div>
      </div>
      <table class="table">
        <thead>
          <tr>
            <th>角色名称</th>
            <th>角色类型</th>
            <th>商户ID</th>
            <th>商户名称</th>
            <th>门店ID</th>
            <th>门店名称</th>
            <th>成员昵称</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="roleLoading" class="loading-row">
            <td colspan="7" class="loading"><div class="spinner"></div>加载中...</td>
          </tr>
          <tr v-else-if="roles.length === 0" class="empty-row">
            <td colspan="7" class="empty">暂无角色关联</td>
          </tr>
          <template v-else>
            <tr v-for="r in roles" :key="r.id || r.Id" class="data-row">
              <td>{{ (r.roleName ?? r.RoleName) || '-' }}</td>
              <td>{{ (r.roleType ?? r.RoleType) ?? '-' }}</td>
              <td>
                <router-link v-if="(r.merchantId ?? r.MerchantId)" class="link" :to="'/merchants/detail/' + (r.merchantId ?? r.MerchantId)">
                  {{ r.merchantId ?? r.MerchantId }}
                </router-link>
                <span v-else>-</span>
              </td>
              <td>{{ merchantNameMap[String(r.merchantId ?? r.MerchantId)] || '-' }}</td>
              <td>
                <router-link v-if="(r.storeId ?? r.StoreId)" class="link" :to="'/stores/detail/' + (r.storeId ?? r.StoreId)">
                  {{ r.storeId ?? r.StoreId }}
                </router-link>
                <span v-else>-</span>
              </td>
              <td>{{ storeNameMap[String(r.storeId ?? r.StoreId)] || '-' }}</td>
              <td>{{ (r.name ?? r.Name) || '-' }}</td>
            </tr>
          </template>
        </tbody>
      </table>
    </div>

    <!-- 账户交易明细（提现记录） -->
    <div class="card slide-up" style="animation-delay: 0.35s" v-if="viewingSelf">
      <div class="table-header"><h3>账户交易明细（提现记录）</h3></div>
      <table class="table">
        <thead>
          <tr>
            <th>提现金额(元)</th>
            <th>手续费(元)</th>
            <th>实际到账(元)</th>
            <th>状态</th>
            <th>支付时间</th>
            <th>创建时间</th>
            <th>交易号</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="withdrawLoading" class="loading-row">
            <td colspan="7" class="loading"><div class="spinner"></div>加载中...</td>
          </tr>
          <tr v-else-if="withdrawals.length === 0" class="empty-row">
            <td colspan="7" class="empty">暂无提现记录</td>
          </tr>
          <template v-else>
            <tr v-for="w in withdrawals" :key="w.Id || w.id">
              <td>{{ formatCents(w.Amount) }}</td>
              <td>{{ formatCents(w.Fee ?? w.ProcedureFee) }}</td>
              <td>{{ formatCents(w.ActualAmount ?? w.ActualFee) }}</td>
              <td>{{ formatWithdrawStatus(w.WithdrawalStatus, w.PayResult) }}</td>
              <td>{{ formatDate(w.PayTime as any) }}</td>
              <td>{{ formatDate(w.CreationTime as any) }}</td>
              <td>{{ w.TransactionNo || '-' }}</td>
            </tr>
          </template>
        </tbody>
      </table>
      <div class="pager">
        <button class="btn secondary" :disabled="withdrawPage <= 1" @click="onWithdrawPrev">上一页</button>
        <span class="pager-info">第 {{ withdrawPage }} / {{ Math.max(1, Math.ceil(withdrawTotal / withdrawLimit)) }} 页</span>
        <button class="btn secondary" :disabled="withdrawPage >= Math.max(1, Math.ceil(withdrawTotal / withdrawLimit))" @click="onWithdrawNext">下一页</button>
      </div>
    </div>

    <!-- 轻提示 -->
    <div v-if="toast.show" class="toast" :class="toast.type">{{ toast.text }}</div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getCurrentUser, getUserVirtualAccount, getUserList, type UserVirtualAccountResponse, type UserListItem } from '../services/user'
import { OrganizationService } from '../services/organization'
import { StoreService } from '../services/store'
import { PaymentService, type WithdrawalRecord } from '../services/payment'
import { isSuccess } from '../services/types'

/**
 * 文件级注释：
 * 用户详情页。展示选中用户的基本信息；若查看的是当前登录用户，则显示其虚拟账户余额；
 * 同时根据成员昵称（key）拉取团队成员列表以展示用户关联角色。
 * 遵循前端 code===0 成功规则。
 */

const route = useRoute()
const router = useRouter()
const userId = String(route.params.id || '')
const nameQuery = String(route.query.name || '')
const phoneQuery = String(route.query.phone || '')

// 轻提示
const toast = reactive<{ show: boolean; text: string; type: 'success' | 'danger' | 'secondary' }>({ show: false, text: '', type: 'secondary' })

// 基本信息（从列表或查询补全）
const basic = reactive<{ name?: string; phone?: string; email?: string; enableStatus?: number; lastLoginTime?: string; creationTime?: string }>({
  name: nameQuery || '',
  phone: phoneQuery || ''
})

// 当前用户与账户信息
const currentUser = ref<any>(null)
const account = reactive<UserVirtualAccountResponse>({})
const viewingSelf = ref(false)
// 头像地址（仅当前用户可获取头像）
const avatarUrl = ref<string | undefined>(undefined)

// 角色列表
const roleLoading = ref(false)
const roles = ref<any[]>([])
// 角色筛选与分页
const roleFilters = reactive<{ key: string; merchantId: string; storeId: string; roleType: number; page: number; limit: number }>({ key: '', merchantId: '', storeId: '', roleType: -1, page: 1, limit: 50 })
// 名称映射缓存
const merchantNameMap = reactive<Record<string, string>>({})
const storeNameMap = reactive<Record<string, string>>({})

/**
 * 函数级注释：日期格式化
 * @param v 原始日期字符串
 * @returns 中文本地时间字符串或 '-'
 */
function formatDate(v?: string) {
  if (!v) return '-'
  try { return new Date(v).toLocaleString('zh-CN') } catch { return v }
}

/**
 * 函数级注释：状态文本
 * @param s 启用状态：1启用，0禁用
 * @returns 中文状态文本
 */
function enableText(s?: number) {
  if (s === 1) return '启用'
  if (s === 0) return '禁用'
  return '未知'
}

/**
 * 函数级注释：状态徽章样式
 * @param s 启用状态
 * @returns 样式类名
 */
function enableBadge(s?: number) { return s === 1 ? 'active' : 'inactive' }

/**
 * 函数级注释：加载基本信息（通过列表按用户名查询并过滤到当前ID）
 * @returns void
 */
async function loadBasic() {
  try {
    const res = await getUserList(1, 50, nameQuery)
    if (isSuccess(res) && res.data?.data) {
      const list = res.data.data as UserListItem[]
      const item = list.find(it => (it.id ?? it.Id) === userId)
      if (item) {
        basic.name = (item.name ?? item.Name) || basic.name
        basic.phone = (item.phone ?? item.Phone) || basic.phone
        basic.email = item.email ?? item.Email
        basic.enableStatus = item.enableStatus ?? item.EnableStatus
        basic.lastLoginTime = item.lastLoginTime ?? item.LastLoginTime
        basic.creationTime = item.creationTime ?? item.CreationTime
      }
    }
  } catch (e: any) {
    showToast(e?.message || '获取基本信息失败', 'danger')
  }
}

/**
 * 函数级注释：加载当前用户与虚拟账户信息
 * @returns void
 */
async function loadAccount() {
  try {
    const cur = await getCurrentUser()
    if (isSuccess(cur)) {
      currentUser.value = cur.data
      viewingSelf.value = String(cur.data?.id || cur.data?.Id || '') === userId
      avatarUrl.value = (cur.data as any)?.avatarUrl
    }
    if (viewingSelf.value) {
      const acc = await getUserVirtualAccount()
      if (isSuccess(acc) && acc.data) {
        Object.assign(account, acc.data)
      }
      await loadWithdrawals()
    }
  } catch (e: any) {
    showToast(e?.message || '获取账户信息失败', 'danger')
  }
}

/**
 * 函数级注释：加载用户关联角色列表（按昵称去重）
 * @returns void
 */
/**
 * 函数级注释：加载用户关联角色列表（调用后端 GetUserRoleMerchantList）
 * @returns void
 * @throws 可能抛出网络或服务端异常
 */
async function loadRoles() {
  roleLoading.value = true
  try {
    const resp = await OrganizationService.getUserRoleMerchantList()
    if (isSuccess(resp) && resp.data) {
      let rows = (resp.data || []) as any[]
      const key = (roleFilters.key || '').trim()
      const mid = (roleFilters.merchantId || '').trim()
      const sid = (roleFilters.storeId || '').trim()
      const rt = roleFilters.roleType
      if (key) rows = rows.filter(r => String(r.name ?? r.Name ?? '').includes(key))
      if (mid) rows = rows.filter(r => String(r.merchantId ?? r.MerchantId ?? '') === mid)
      if (sid) rows = rows.filter(r => String(r.storeId ?? r.StoreId ?? '') === sid)
      if (rt !== -1) rows = rows.filter(r => Number(r.roleType ?? r.RoleType ?? -1) === rt)
      roles.value = rows
      await prefetchNamesForRoles(roles.value)
    } else {
      roles.value = []
      showToast(resp?.message || '获取角色列表失败', 'danger')
    }
  } catch (e: any) {
    roles.value = []
    showToast(e?.message || '接口异常', 'danger')
  } finally {
    roleLoading.value = false
  }
}

/**
 * 函数级注释：预取角色关联的商户/门店名称并缓存
 * @param rows 角色数据行
 * @returns void
 */
async function prefetchNamesForRoles(rows: any[]) {
  const mids = new Set<string>()
  const sids = new Set<string>()
  rows.forEach(r => {
    const mid = String(r.merchantId ?? r.MerchantId ?? '')
    const sid = String(r.storeId ?? r.StoreId ?? '')
    if (mid) mids.add(mid)
    if (sid) sids.add(sid)
  })
  await Promise.all(Array.from(mids).map(async id => {
    if (!merchantNameMap[id]) {
      try {
        const m = await OrganizationService.getMerchantDetail(id)
        if (isSuccess(m) && m.data) merchantNameMap[id] = (m.data.name ?? '-') as string
      } catch { /* 忽略单个异常 */ }
    }
  }))
  await Promise.all(Array.from(sids).map(async id => {
    if (!storeNameMap[id]) {
      try {
        const s = await StoreService.getStoreDetail(id)
        if (isSuccess(s) && s.data) storeNameMap[id] = (s.data.name ?? '-') as string
      } catch { /* 忽略单个异常 */ }
    }
  }))
}

/**
 * 函数级注释：加载提现记录（分页）
 * @returns void
 */
const withdrawLoading = ref(false)
const withdrawals = ref<WithdrawalRecord[]>([])
const withdrawPage = ref(1)
const withdrawLimit = ref(10)
const withdrawTotal = ref(0)

async function loadWithdrawals() {
  if (!viewingSelf.value) return
  withdrawLoading.value = true
  try {
    const resp = await PaymentService.getWithdrawalRecordList(withdrawPage.value, withdrawLimit.value)
    if (isSuccess(resp) && resp.data) {
      withdrawals.value = resp.data.data || []
      withdrawTotal.value = resp.data.total || 0
    } else {
      withdrawals.value = []
      withdrawTotal.value = 0
      showToast(resp?.message || '获取提现记录失败', 'danger')
    }
  } catch (e: any) {
    showToast(e?.message || '接口异常', 'danger')
  } finally {
    withdrawLoading.value = false
  }
}

/**
 * 函数级注释：格式化分为元
 * @param n 分
 * @returns 元字符串（两位小数）
 */
function formatCents(n?: number) { const v = Number(n ?? 0); return (v / 100).toFixed(2) }

/**
 * 函数级注释：提现状态文案
 * @param s 系统提现状态（0/1/2/3）
 * @param payResult 渠道状态（00/01/03/04）
 * @returns 中文状态文本
 */
function formatWithdrawStatus(s?: number, payResult?: string) {
  if (s === 1) return '成功'
  if (s === 2) return '失败'
  if (s === 3) return '延迟处理中'
  if (s === 0) return '处理中'
  if (payResult === '00') return '成功'
  if (payResult === '01') return '失败'
  if (payResult === '03') return '处理中'
  if (payResult === '04') return '延迟处理中'
  return '未知'
}

/**
 * 函数级注释：翻页到上一页
 * @returns void
 */
function onWithdrawPrev() { if (withdrawPage.value > 1) { withdrawPage.value--; loadWithdrawals() } }
/**
 * 函数级注释：翻页到下一页
 * @returns void
 */
function onWithdrawNext() {
  const max = Math.max(1, Math.ceil(withdrawTotal.value / withdrawLimit.value))
  if (withdrawPage.value < max) { withdrawPage.value++; loadWithdrawals() }
}

/**
 * 函数级注释：搜索角色列表（应用筛选）
 * @returns void
 */
function searchRoles() {
  roleFilters.page = 1
  loadRoles()
}

/**
 * 函数级注释：重置角色筛选
 * @returns void
 */
function resetRoleFilters() {
  roleFilters.key = ''
  roleFilters.merchantId = ''
  roleFilters.storeId = ''
  roleFilters.roleType = -1
  roleFilters.page = 1
  loadRoles()
}

/**
 * 函数级注释：返回上一页
 * @returns void
 */
function goBack() { router.back() }

// 需求调整：前端不提供复制ID与复制手机号操作，故移除相关方法与按钮。

/**
 * 函数级注释：刷新整页数据
 * @returns void
 */
async function refreshPage() {
  await loadBasic()
  await loadAccount()
  await loadRoles()
}

/**
 * 函数级注释：显示轻提示
 * @param text 文本
 * @param type 类型：success/danger/secondary
 * @returns void
 */
function showToast(text: string, type: 'success' | 'danger' | 'secondary' = 'secondary') {
  toast.text = text
  toast.type = type
  toast.show = true
  setTimeout(() => { toast.show = false }, 2000)
}

onMounted(async () => {
  await loadBasic()
  await loadAccount()
  await loadRoles()
})
</script>

<style scoped>
.header { display:flex; align-items:center; justify-content:space-between; }
.filters { padding: var(--space-3); }
.filter-row { display:flex; flex-wrap: wrap; align-items:center; gap: var(--space-3); }
.filter-label { color: var(--text-secondary); }
.grid { display:grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.grid-item { display:flex; flex-direction: column; gap: var(--space-2); }
.grid-item label { color: var(--text-secondary); }
.table { width: 100%; border-collapse: collapse; }
.table th, .table td { padding: 12px; border-bottom: 1px solid var(--border); }
.table thead th { text-align: left; color: var(--text-secondary); font-weight: 600; }
.link { color: var(--primary-600); text-decoration: underline; }
.badge { padding: 2px 8px; border-radius: var(--radius); font-size: var(--text-sm); }
.badge.active { background: var(--success-50); color: var(--success-700); }
.badge.inactive { background: var(--secondary-100); color: var(--text-secondary); }
.loading-row .loading { text-align:center; }
.spinner { width: 20px; height: 20px; border: 2px solid var(--border); border-top-color: var(--primary); border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto; }
@keyframes spin { to { transform: rotate(360deg); } }
.hint { color: var(--text-secondary); font-size: var(--text-sm); }
.toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); padding: 10px 16px; border-radius: var(--radius); background: var(--card-bg); color: var(--text); border: 1px solid var(--border); box-shadow: var(--shadow-sm); z-index: 1001; }
.toast.success { border-color: var(--success-300); }
.toast.danger { border-color: var(--danger-300); }
.avatar { width: 64px; height: 64px; border-radius: 50%; border: 1px solid var(--border); object-fit: cover; }
.avatar.placeholder { display:flex; align-items:center; justify-content:center; background: var(--secondary-100); color: var(--text-secondary); font-size: 24px; }
.avatar-wrap { display:flex; align-items:center; gap: var(--space-2); }
.pager { display:flex; align-items:center; gap: var(--space-3); padding: var(--space-3) 0; }
.pager-info { color: var(--text-secondary); }
</style>
